fn main() {
    // ownership rules
    // 1. Each value in Rust has a variable that’s called its owner.
    // 2. There can only be one owner at a time.
    // 3. When the owner goes out of scope, the value will be dropped.

    // ownership and binding
    // 变量绑定拥有数据的所有权。
    //      一份数据同时只能有一个所有者。
    // 如果一个绑定超出作用域，其绑定的数据将被自动释放。
    //      对于在堆上分配的数据，这意味着释放空间。

    let mut v1 = foo();
    v1.push(5);
    println!("{:?}", v1); // macro will not take ownership of v1
    v1.push(6);
    println!("{:?}", v1);

    println!("{}", vec_length(&v1));
    println!("{:?}", v1); // v1 has been moved to vec_length

    let v = vec![1, 2, 3];
    let v_ref = &v; // v_ref 在后续代码没有被使用
    let v_new = v; // 早期版本，v_ref 还持有 v 的引用，不允许 v 被移动
                   // 非词法生命周期 (NLL, non-lexical lifetime)
                   // 1. 一个变量的引用在作用域内没有被使用
                   // 2. 一个变量的引用在作用域内没有被修改
    println!("{:?}", v_new);

    // range of a vector
    // #1 mutable reference
    let mut v = vec![1, 2, 3];
    for ele in &mut v {
        *ele += 50;
        println!("ele: {}", ele);
    }

    // #2 immutable reference
    for ele in v.iter() {
        println!("mut ele: {}", ele);
    }

    // #3 ownership
    for ele in v {
        println!("immut ele: {}", ele);
    }
    // println!("{:?}", v); // v has been moved to for loop

    // slice
    let a = [1, 2, 3, 4, 5];
    let slice = &a[1..3];
    assert_eq!(slice, &[2, 3]);
}

fn vec_length(v: &Vec<i32>) -> usize {
    v.len()
}

fn vec_length_taking_ownership(v: Vec<i32>) -> usize {
    v.len()
}

fn foo() -> Vec<i32> {
    let mut v1 = vec![1, 2, 3];
    v1.pop();
    v1.push(4);
    v1
}
